import React, { useReducer,createContext, useContext } from "react"
// 使用useReducer和usecontext来进行通信和管理状态
// 使用useReducer先定义一个初始状态和reducer
const defaultState = { name: 'kun', age: 8.5 }

const reducer = (preState, action) => {
    console.log(action, '--action');
    console.log('触发了reducer的执行');
    switch (action.type) {
        case 'UPDATE_NAME':
            return { ...preState, name: action.payload }
        case 'UPDATE_AGE':
            return { ...preState, age: action.payload }
        case 'ICREMENT':
            return { ...preState, age: action.payload + preState.age }
        case 'DECREMENT':
            return { ...preState, age: preState.age - action.payload }
        case 'RESET':
            return {...defaultState,age:Math.round(Math.abs(defaultState.age))}
        default:
            return preState
    }


}
// 对初始状态进行处理 赋予给state
const initAction = (initState) => {
    return { ...initState, age: Math.round(Math.abs(initState.age)) }
}

// 使用useContext进行跨组件通信
const MyContext=createContext({})


export const Wrapper=(props)=>{
    // 若没有initAction，则state就是defaultState。
    // 有initAction，则需要对defaultState做预处理，再赋予给state
    const [state, dispatch] = useReducer(reducer, defaultState, initAction)

    return<>
    <MyContext.Provider value={{state, dispatch}}>{props.children}</MyContext.Provider>
    </>
}

export const Father1 = () => {
    const  {state, dispatch}  = useContext(MyContext)
    
   
    const reWrite = () => {
        // 想修改state 不可以直接修改state.name，这样react是响应不到的
        // type是必须要传递的
        // 每次调用dispatch()时，React都会检查reducer返回的新状态是否与旧状态不同。由于您的reducer总是返回旧状态，从技术上讲，状态没有变化，但React的更新机制仍然会触发组件的重新渲染流程
        dispatch({ type: 'UPDATE_NAME', payload: '坤' })
    }
    return (
        <div>
            <button onClick={reWrite}>修改用户名</button>
            <p>{JSON.stringify(state)}</p>
            <div className="father">
                <Son1   />
                <Son2   />
            </div>
        </div>
    )
}
const Son1 = () => {
    const  {state, dispatch}  = useContext(MyContext)
    // 使得age+1 每个组件都会改变
    const add = () => {
        dispatch({ type: 'ICREMENT', payload: 1 })
    }
    return <div className="son1">
        <p>{JSON.stringify(state)}</p>
        <button onClick={add}>+1</button>
    </div>
}


// 实现年龄-5
const Son2 = () => {
    const {state,dispatch}=useContext(MyContext)

    const delete1 = () => {
        dispatch({ type: 'DECREMENT', payload: 5 })
    }


    return <div className="son2">
        <p>{JSON.stringify(state)}</p>
        <button onClick={delete1}>-5</button>
        <hr></hr>
        <GrandSon />
    </div>
}

// 进行重置数据
const GrandSon=()=>{
    const {dispatch}=useContext(MyContext)
    const reset=()=>{
        dispatch({type:'RESET'})
    }
    return <>
    <button onClick={reset}>重置</button>
    </>
}